package com.erp.wallet.listener;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.erp.wallet.domain.ErpDistributionUserIncome;
import com.ruoyi.wallet.api.domain.ErpDistributionUserWallet;
import com.erp.wallet.domain.ErpDistributionUserWalletBill;
import com.erp.wallet.mapper.ErpDistributionUserIncomeMapper;
import com.erp.wallet.mapper.ErpDistributionUserWalletBillMapper;
import com.erp.wallet.mapper.ErpDistributionUserWalletMapper;
import com.rabbitmq.client.Channel;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteSysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * @Description: 销售系统（ERP、代理、市级合伙人）监听
 * @Author: j.zh
 * @Date: 2024/5/2
 * @Version: 4.0.0
**/
@Slf4j
@Component
@RabbitListener(queues = "distribution.sale.system.queue", ackMode = "MANUAL")
public class SaleSystemDistributionListener {

    @Resource
    RemoteSysConfigService configService;
    @Resource
    ErpDistributionUserWalletMapper userWalletMapper;
    @Resource
    ErpDistributionUserWalletBillMapper userWalletBillMapper;
    @Resource
    ErpDistributionUserIncomeMapper userIncomeMapper;

    /**
     * 销售系统分配提成
     *
     * @param info
     * @param channel
     * @param message
     * @throws IOException
     */
    @RabbitHandler
    public void listener(String info, Channel channel, Message message) throws IOException {

        try {
            log.debug("=============接收消息，消息队列开始执行（销售系统分配提成）");
            // 回复队列消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            // 将JSON字符串转换为Map
            JSONObject divideJson = JSONObject.parseObject(info);
            Map<String, Object> divideMap = (Map<String, Object>)divideJson;
            divide(divideMap);
        } catch (Exception e) {
            // TODO 消费异常，设置入库操作

            System.out.println("=============执行异常：" + e.toString());
        }

    }


    /**
     * @Description: 销售系统提成分配
     * @Author: j.zh
     * @Date: 2024/5/2
     * @param divideMap
     * @Version: 4.0.0
    **/
    @Transactional
    public void divide(Map<String, Object> divideMap) {
        // 获取分销类型：分公司、代理、个人ERP
        Integer distributionType = (Integer) divideMap.get("distributionType");
        // 获取待分销金额
        BigDecimal distributionAmount = new BigDecimal(divideMap.get("distributionAmount").toString());
        // 本次是否分佣，不分，则只需变更公司钱包，分，则根据推荐人类型及提成比例，按比例分配并更新钱包数据
        Integer isDivide = (Integer) divideMap.get("isDistribution");
        // 分佣方式
        Integer divideMode = (Integer) divideMap.get("distributionMode");

        ErpDistributionUserWallet userWallet = null;

        // 判断分销还是不分销
        if (isDivide.intValue() == 0){
            // 不在线分佣
            if(divideMode.intValue() == 1){
                // TODO 自定义分销
            }else {
                /**
                 * 固定数据不分销，按系统配置的数据分配，即：
                 * 如果是分公司，则变更公司钱包可提现和累积收益
                 * 如果是代理，则变更总公司可提现和累积收益，分公司的累积收益
                 * 如果是个人，则变更总公司可提现和累积收益，分公司的累积收益，代理的累积收益
                 **/
                switch (distributionType){
                    case 1:
                        // 变更总公司钱包数据及相关记录
                        userWallet = userWalletMapper.selectById(1l);
                        insertBySaleSystemAmount(userWallet, 0, 1,
                                distributionAmount, divideMap.get("remarks").toString(), "sale-branch",
                                "offline", null, null);
                        break;
                    case 2:
                        // 即代理，则查询该代理的推荐分公司
                        if(!divideMap.containsKey("parentBranchId") || divideMap.get("parentBranchId").toString().equals("1")){
                            // 推荐的公司是总公司
                            userWallet = userWalletMapper.selectById(1l);
                            insertBySaleSystemAmount(userWallet, 0, 1,
                                    distributionAmount, divideMap.get("remarks").toString(), "sale-agent",
                                    "offline", null, null);
                        }else {
                            // 1、获取分公司比例
                            BigDecimal officeAmountScale = new BigDecimal(configService.getConfigKey("office_amount_scale").getMsg());
                            // 2、获取总公司比例
                            BigDecimal headAmountScale = new BigDecimal("1").subtract(officeAmountScale);
                            // 3、获取总公司钱包并变更钱包数据及相关记录
                            userWallet = userWalletMapper.selectById(1l);
                            insertBySaleSystemAmount(userWallet, 0, 2,
                                    distributionAmount.multiply(headAmountScale), divideMap.get("remarks").toString(), "sale-agent",
                                    "offline", null, null);
                            // 4、获取分公司钱包并变更钱包数据及相关记录
                            Long parentBranchId = Long.parseLong(divideMap.get("parentBranchId").toString());
                            userWallet = userWalletMapper.selectOne(new LambdaQueryWrapper<ErpDistributionUserWallet>()
                                    .eq(ErpDistributionUserWallet::getDistributionUserId, parentBranchId));
                            insertBySaleSystemAmount(userWallet, 0, 2,
                                    distributionAmount.multiply(officeAmountScale), divideMap.get("remarks").toString(), "sale-agent",
                                    "offline", null, null);
                        }
                        break;
                    case 3:
                        // 个人ERP系统，设置已分配的比例
                        BigDecimal allocatedScale = new BigDecimal("0");
                        // 获取公司比例
                        BigDecimal headAmountScale = new BigDecimal("1");
                        // 获取代理比例
                        BigDecimal agentAmountScale = new BigDecimal(configService.getConfigKey("agent_amount_scale").getMsg());
                        // 获取分公司比例
                        BigDecimal officeAmountScale = new BigDecimal(configService.getConfigKey("office_amount_scale").getMsg());
                        // 代理人分佣
                        if (divideMap.containsKey("parentAgentId")){
                            // 有代理，获取代理钱包并变更钱包数据及相关记录
                            Long parentAgentId = Long.parseLong(divideMap.get("parentAgentId").toString());
                            userWallet = userWalletMapper.selectOne(new LambdaQueryWrapper<ErpDistributionUserWallet>()
                                    .eq(ErpDistributionUserWallet::getDistributionUserId, parentAgentId));
                            insertBySaleSystemAmount(userWallet, 0, 3,
                                    distributionAmount.multiply(agentAmountScale), divideMap.get("remarks").toString(), "sale-erp",
                                    "offline", null, null);
                            allocatedScale = allocatedScale.add(agentAmountScale);
                        }
                        // 分公司分佣
                        if (divideMap.containsKey("parentBranchId")){
                            // 有分公司，获取分公司钱包并变更钱包数据及相关记录
                            Long parentBranchId = Long.parseLong(divideMap.get("parentBranchId").toString());
                            userWallet = userWalletMapper.selectOne(new LambdaQueryWrapper<ErpDistributionUserWallet>()
                                    .eq(ErpDistributionUserWallet::getDistributionUserId, parentBranchId));
                            officeAmountScale = officeAmountScale.subtract(allocatedScale);
                            insertBySaleSystemAmount(userWallet, 0, 3,
                                    distributionAmount.multiply(officeAmountScale), divideMap.get("remarks").toString(), "sale-erp",
                                    "offline", null, null);
                            allocatedScale = allocatedScale.add(officeAmountScale);
                        }
                        // 总公司
                        userWallet = userWalletMapper.selectById(1l);
                        insertBySaleSystemAmount(userWallet, 0, 3,
                                distributionAmount.multiply(headAmountScale.subtract(allocatedScale)), divideMap.get("remarks").toString(), "sale-erp",
                                "offline", null, null);
                        break;
                    default:
                        break;
                }

            }
        }
    }

    /**
     * @Description: 变更钱包数据及相关记录
     * @Author: j.zh
     * @Date: 2024/5/3
     * @param userWallet
     * @param isDivide
     * @param incomeType
     * @param distributionAmount
     * @param remarks
     * @param incomeSource
     * @param orderSource
     * @param orderId
     * @param orderNumber
     * @Version: 4.0.0
    **/
    private void insertBySaleSystemAmount(ErpDistributionUserWallet userWallet, Integer isDivide, Integer incomeType,
                                          BigDecimal distributionAmount, String remarks, String incomeSource,
                                          String orderSource, String orderId, String orderNumber){
        // 1、变更钱包数据

        // 是否分销或者是总公司账户
        if (isDivide.intValue() == 1 || userWallet.getDistributionUserId().intValue() == 1){
            // 分销或总公司，累加可提现
            userWallet.setSettledAmount(userWallet.getSettledAmount().add(distributionAmount));
        }
        // 累积收益
        userWallet.setAccrueAmount(userWallet.getAccrueAmount().add(distributionAmount));
        userWalletMapper.updateById(userWallet);
        // 2、新增钱包流水
        userWalletBillMapper.insert(new ErpDistributionUserWalletBill(userWallet, remarks,
                new BigDecimal("0"),
                (isDivide.intValue() == 1 || userWallet.getDistributionUserId().intValue() == 1) ? distributionAmount : new BigDecimal("0"),
                new BigDecimal("0"), new BigDecimal("0"), distributionAmount, new BigDecimal("0"),0));
        // 3、新增收支记录
        ErpDistributionUserIncome userIncome = new ErpDistributionUserIncome();
        userIncome.setDistributionUserId(userWallet.getDistributionUserId());
        userIncome.setWalletId(userWallet.getWalletId());
        // TODO 待更新收支类型字典表
        userIncome.setIncomeType(incomeType);
        // TODO 待更新收支状态字典表
        userIncome.setState(1);
        userIncome.setIncomeAmount(distributionAmount);
        userIncome.setIncomeSource(incomeSource);
        userIncome.setOrderSource(orderSource);
        userIncome.setOrderId(orderId);
        userIncome.setOrderNumber(orderNumber);
        userIncome.setCreateTime(new Date());
        userIncome.setModifier(1l);
        userIncomeMapper.insert(userIncome);
    }
}
